package com.witmore.skyline.web.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.witmore.skyline.db.entity.CameraDO;
import com.witmore.skyline.db.mapper.CameraMapper;
import com.witmore.skyline.web.service.DeviceService;
import com.witmore.skyline.web.service.third.tplink.ApiCaptureUrlClient;
import com.witmore.skyline.web.service.third.tplink.dto.DeviceResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Profile({"prod"})
@Slf4j
@Service
public class MyScheduledTask {

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private CameraMapper cameraMapper;


    /**
     * 每3个小时拉一次设备列表数据
     */
    @Scheduled(fixedRate = 3600000 * 3)
    public void executeSyncDeviceListTask() {
        log.info("Executing syncDeviceList task every 3 hours at {}", System.currentTimeMillis());
        try {
            deviceService.getAndSaveDeviceListFromCloudm();
        } catch (Exception e) {
            log.error("executeSyncDeviceListTask失败 error msg-->{}, e",
                    e.getMessage(), e);
        }
    }


    /**
     * 每2分钟拉一次设备详情数据
     */
    @Scheduled(fixedRate = 120000)
    public void executeSyncDeviceDetailTask() {
        log.info("Executing syncDeviceDetail task every 2 minutes at {}", System.currentTimeMillis());
        try {
            deviceService.deviceFieldMaintenanceFromCloudm(null);
        } catch (Exception e) {
            log.error("executeSyncDeviceDetailTask失败 error msg-->{}, e",
                    e.getMessage(), e);
        }
    }

    /**
     * 拉取昨日设备日报数据
     */
    @Scheduled(cron = "3 0 5,12,21 * * ?")
    public void executeSyncDeviceDailyReportTask() {
        log.info("Executing syncDeviceDailyReport task every day at 1:00 am {}", System.currentTimeMillis());
        try {
            // 获取昨天的日期
            LocalDate yesterday = LocalDate.now().plusDays(-1);
            deviceService.deviceDailyFromCloudm(yesterday, yesterday, null);
        } catch (Exception e) {
            log.error("executeSyncDeviceDailyReportTask失败 error msg-->{}, e",
                    e.getMessage(), e);
        }
    }

    /**
     * 每天凌晨0点当天工时字段置空
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void executeSyncDeviceTodayWorkTimeTask() {
        log.info("Executing syncDeviceTodayWorkTime task every day at 0:00 am {}", System.currentTimeMillis());
        try {
            deviceService.deviceTodayWorkTimeReset();
        } catch (Exception e) {
            log.error("executeSyncDeviceTodayWorkTimeTask失败 error msg-->{}, e",
                    e.getMessage(), e);
        }
    }

    /**
     * 每隔10分钟拉取一下设备工时
     */
    @Scheduled(fixedRate = 600000)
    public void executeSyncDeviceWorkTimeTask() {
        log.info("Executing syncDeviceWorkTime task every 10 minutes at {}", System.currentTimeMillis());
        try {
            deviceService.deviceTodayWorkTimeFromCloudm();
        } catch (Exception e) {
            log.error("executeSyncDeviceWorkTimeTask失败 error msg-->{}, e",
                    e.getMessage(), e);
        }
    }

    /**
     * 每2分钟扫描摄像头表，更新摄像头在线状态
     */
    @Scheduled(fixedRate = 120000)
    public void executeSyncCameraStatusTask() {
        log.info("Executing syncCameraStatus task every 2 minutes at {}", System.currentTimeMillis());
        try {
            updateCameraOnlineStatus();
        } catch (Exception e) {
            log.error("executeSyncCameraStatusTask失败 error msg-->{}", e.getMessage(), e);
        }
    }


    /**
     * 更新摄像头在线状态（分页处理）
     */
    private void updateCameraOnlineStatus() {
        // 每页处理50个摄像头，可根据实际情况调整
        final int pageSize = 50;
        int currentPage = 1;
        int totalSuccessCount = 0;
        int totalFailCount = 0;
        int totalProcessedCount = 0;

        log.info("开始分页更新摄像头在线状态，每页处理{}个", pageSize);

        while (true) {
            // 分页查询未删除的TPLink摄像头（type=2表示TPLink摄像头）
            Page<CameraDO> page = new Page<>(currentPage, pageSize);
            LambdaQueryWrapper<CameraDO> queryWrapper = new LambdaQueryWrapper<CameraDO>()
                    .eq(CameraDO::getIsDeleted, 0)
                    .eq(CameraDO::getType, 2)
                    .isNotNull(CameraDO::getCameraSn)
                    .orderByAsc(CameraDO::getId); // 添加排序确保分页稳定

            Page<CameraDO> cameraPage = cameraMapper.selectPage(page, queryWrapper);
            List<CameraDO> cameraList = cameraPage.getRecords();

            if (CollectionUtils.isEmpty(cameraList)) {
                if (currentPage == 1) {
                    log.info("没有找到需要更新状态的TPLink摄像头");
                }
                break;
            }

            log.info("处理第{}页，共{}个摄像头", currentPage, cameraList.size());

            int pageSuccessCount = 0;
            int pageFailCount = 0;

            // 处理当前页的摄像头
            for (CameraDO camera : cameraList) {
                try {
                    // 调用ApiCaptureUrlClient.getDeviceInfo获取设备信息
                    DeviceResultDTO deviceInfo = ApiCaptureUrlClient.getDeviceInfo(camera.getCameraSn());

                    if (deviceInfo == null){
                        log.warn("摄像头{}未找到", camera.getCameraSn());
                        continue;
                    }
                    Integer newStatus = 0; // 默认离线
                    if (deviceInfo.getDeviceStatus() != null) {
                        newStatus = deviceInfo.getDeviceStatus();
                    }

                    // 只有状态发生变化时才更新数据库
                    if (!newStatus.equals(camera.getCameraStatus())) {
                        LambdaUpdateWrapper<CameraDO> updateWrapper = new LambdaUpdateWrapper<CameraDO>()
                                .eq(CameraDO::getId, camera.getId())
                                .set(CameraDO::getCameraStatus, newStatus)
                                .set(CameraDO::getModelName, deviceInfo.getDeviceModel())
                                .set(CameraDO::getUpdateTime, LocalDateTime.now());

                        int updateResult = cameraMapper.update(null, updateWrapper);
                        if (updateResult > 0) {
                            log.debug("摄像头{}状态更新成功: {} -> {}",
                                    camera.getCameraSn(), camera.getCameraStatus(), newStatus);
                            pageSuccessCount++;
                        } else {
                            log.warn("摄像头{}状态更新失败", camera.getCameraSn());
                            pageFailCount++;
                        }
                    } else {
                        // 状态未变化，仍然计入成功
                        pageSuccessCount++;
                    }

                } catch (Exception e) {
                    log.error("更新摄像头{}状态时发生异常: {}", camera.getCameraSn(), e.getMessage());
                    pageFailCount++;
                }
            }

            totalSuccessCount += pageSuccessCount;
            totalFailCount += pageFailCount;
            totalProcessedCount += cameraList.size();

            log.info("第{}页处理完成，成功: {}, 失败: {}", currentPage, pageSuccessCount, pageFailCount);

            // 检查是否还有下一页
            if (cameraList.size() < pageSize) {
                // 当前页数据量小于页大小，说明已经是最后一页
                break;
            }

            currentPage++;

            // 可选：在处理页面之间添加短暂延迟，避免对数据库和外部API造成过大压力
            try {
                Thread.sleep(100); // 100毫秒延迟
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("定时任务被中断");
                break;
            }
        }

        log.info("摄像头状态更新完成，共处理{}个，成功: {}, 失败: {}",
                totalProcessedCount, totalSuccessCount, totalFailCount);
    }

}
